package com.thank.concurrency.samples.deadLock;

import lombok.extern.slf4j.Slf4j;

/**
 * 演示一个简单的死锁类
 * 当DeadLockExample类的对象flag==1时(example1), 先锁定o1, 睡眠1秒
 * 而当example1在睡眠的时候另一个flag==0的对象(example2)线程启动了, 先锁定了喔o2, 同样睡眠1秒
 * example1睡眠结束后需要锁定o2才能继续执行, 而此时o2已被example2锁定了;
 * example2睡眠结束后需要锁定o1才能继续执行, 而此时o1已被example1锁定了;
 * example1, example2相互等待, 都需要得到对方锁定的资源才能继续执行, 从而造成死锁
 *
 */
@Slf4j
public class DeadLockExample implements Runnable {

    public int flag = 1;

    // 静态对象的类是所有对象共有的
    private static Object o1 = new Object(), o2 = new Object();

    @Override
    public void run() {
        log.info("flag:{}", flag);
        if (1==flag) {
            synchronized (o1) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (o2) {
                    log.info("i lock o2");
                }
            }
        }

        if (0==flag) {
            synchronized (o2) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (o1) {
                    log.info("i lock o1");
                }
            }
        }
    }

    public static void main(String[] args) {
        DeadLockExample example1 = new DeadLockExample();
        DeadLockExample example2 = new DeadLockExample();
        example1.flag = 1;
        example2.flag = 0;

        // example1和example1都处于可执行状态, 但JVM线程调度先执行哪个线程是不固定的
        new Thread(example1).start();
        new Thread(example2).start();
    }
}
